
package wviz.gui;

import javax.swing.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.*;

/**
 * A component used as a semi-transparent glass pane for disabling visualisation graph during graph generation.
 * It is also a mouse listener that consume mouse events and does not allow events to reach to underlying disabled component.
 */
public class DisabledGlassPane extends JComponent implements MouseListener {

    private Color disabledColor = new Color(Color.gray.getRed(), Color.gray.getGreen(), Color.gray.getBlue(), 70);
    private final JComponent toBeDisabled;
    private Rectangle rect; //the gray rectanagle

    public DisabledGlassPane(JComponent toBeDisabled) {
        this.toBeDisabled = toBeDisabled;
        this.addMouseListener(this);
    }

    @Override
    protected void paintComponent(Graphics g) {
        if (toBeDisabled != null) {
            g.setColor(disabledColor);
            g.fillRect((int) rect.getX(), (int) rect.getY(), (int) rect.getWidth(), (int) rect.getHeight());
        }
    }

    public void hidePane() {
        this.setVisible(false);
    }

    public void showPane() {
        this.setVisible(true);
        rect = toBeDisabled.getBounds();
        rect = SwingUtilities.convertRectangle(toBeDisabled, rect, toBeDisabled.getRootPane());
    }

    public void mouseClicked(MouseEvent e) {
        checkAndConsume(e);
    }

    private void checkAndConsume(MouseEvent e) {
        if (!isVisible())
            return;
        //Point point = e.getLocationOnScreen();
        //SwingUtilities.convertPointFromScreen(point, toBeDisabled);
        if (rect.contains(e.getPoint()))
            e.consume();
        else {
            //re dispatch event
            //first we convert the point of the mouse clicked to a point on main window (content pane)
            Point pt = SwingUtilities.convertPoint(this, e.getPoint(), this.getRootPane().getContentPane());
            //second find the component bellow the glass pane
            Component component = SwingUtilities.getDeepestComponentAt(this.getRootPane().getContentPane(), pt.x, pt.y);
            if (component != null) {
                //we need to convert the point to be undestandable for "component"
                Point cmpPt = SwingUtilities.convertPoint(this, e.getPoint(), component);
                //and also we need to recreate mouse event and pass "component" as a source
                component.dispatchEvent(new MouseEvent(component,
                        e.getID(),
                        e.getWhen(),
                        e.getModifiers(),
                        cmpPt.x,
                        cmpPt.y,
                        e.getClickCount(),
                        e.isPopupTrigger(), e.getButton()));
            }
        }
    }

    public void mousePressed(MouseEvent e) {
        checkAndConsume(e);
    }

    public void mouseReleased(MouseEvent e) {
        checkAndConsume(e);
    }

    public void mouseEntered(MouseEvent e) {
        checkAndConsume(e);
    }

    public void mouseExited(MouseEvent e) {
        checkAndConsume(e);
    }
}